package com.cbc.ourgame.slideshowmaker.view
{
	import com.cbc.ourgame.slideshowmaker.components.DragDropIcon;
	import com.cbc.ourgame.slideshowmaker.components.ui.ToolTip;
	import com.cbc.ourgame.slideshowmaker.events.TimelineDataEvent;
	import com.cbc.ourgame.slideshowmaker.model.datastructures.TimelineData;
	
	import flash.display.Stage;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Keyboard;
	
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	public class StageMediator extends Mediator
	{
		public static const NAME:String = "StageMediator";
		public static const DRAG_TEST:String = "dragTest";
		public static const DROP_TEST:String = "dropTest";
		public static const SHOW_TOOL_TIP:String = "showToolTip";
		public static const HIDE_TOOL_TIP:String = "hideToolTip";
		public static const DELETE_PRESSED:String = "deletePressed";
		
		private const MOVE_TEST_PIXELS:Number = 10;
		
		private var _dragDropIcon:DragDropIcon;
		private var _startPoint:Point;
		private var _toolTip:ToolTip;
		
		public function get stage():Stage
		{
			return viewComponent as Stage;
		}
		
		public function StageMediator(viewComponent:Stage)
		{
			_toolTip = new ToolTip();
			_toolTip.text = "DRAG TO TIMELINE";
			_dragDropIcon = new DragDropIcon();
			super(NAME, viewComponent);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
		}
		
		override public function onRegister():void
		{
				
		}
		
		override public function listNotificationInterests():Array
		{
			return [
						TimelineDataEvent.LIBRARY_DRAG,
						TimelineDataEvent.TIMELINE_DRAG,
						SHOW_TOOL_TIP,
						HIDE_TOOL_TIP
					];
		}
		
		override public function handleNotification(note:INotification):void
		{
			switch(note.getName())
			{
				case TimelineDataEvent.LIBRARY_DRAG:
				case TimelineDataEvent.TIMELINE_DRAG: 
					_dragDropIcon.dragType = note.getName(); 
					_dragDropIcon.data = TimelineData(note.getBody()); 
				break;
				case SHOW_TOOL_TIP: showToolTip(); break;
				case HIDE_TOOL_TIP: hideToolTip(); break; 
			}
		}
		
		private function showToolTip():void
		{
			stage.addChild(_toolTip);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, moveToolTip);
			_toolTip.show();
		}
		
		private function hideToolTip():void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveToolTip);
			_toolTip.hide();
		}
		
		private function moveToolTip(e:MouseEvent):void
		{
			_toolTip.x = stage.mouseX + 15;
			_toolTip.y = stage.mouseY;
		}
		
		private function onMouseUp(e:MouseEvent):void
		{
			_dragDropIcon.hasData = false;
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			
			if(_dragDropIcon.isActive)
			{ 
				_dragDropIcon.remove();
				sendNotification(DROP_TEST, _dragDropIcon.timelineData);	
			}
		}
		
		private function onMouseDown(e:MouseEvent):void
		{
			_startPoint = new Point(stage.mouseX, stage.mouseY);
			_dragDropIcon.move(stage.mouseX - 30, stage.mouseY - 30);
			
			if(_dragDropIcon.hasData)
			{
				stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
				stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			}	
			
			if(_dragDropIcon.dragType == TimelineDataEvent.TIMELINE_DRAG)
			{
				_dragDropIcon.show(stage);
				sendDragNotification();
			}
		}
		
		private function onMouseMove(e:MouseEvent):void
		{
			var testY:Boolean = Math.abs(stage.mouseX - _startPoint.x) > MOVE_TEST_PIXELS;
			var testX:Boolean = Math.abs(stage.mouseY - _startPoint.y) > MOVE_TEST_PIXELS;
			
			if(testX || testY) 
				_dragDropIcon.show(stage);
			
			_dragDropIcon.move(stage.mouseX - _dragDropIcon.width/2, stage.mouseY - _dragDropIcon.height/2);
			sendDragNotification();
		}
		
		private function sendDragNotification():void
		{
			sendNotification(DRAG_TEST, _dragDropIcon.dropTestArea);
		}
		
		private function onKeyDown(e:KeyboardEvent):void
		{
			if(e.keyCode == Keyboard.BACKSPACE || e.keyCode == Keyboard.DELETE) sendNotification(DELETE_PRESSED);
		}
		
	}
}